// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef LEMC_JOB_H
#define LEMC_JOB_H

#include <RakPeerInterface.h>
#include <MessageIdentifiers.h>
#include <RakNetTypes.h>
#include <BitStream.h>
#include <string>
#include <array>

#include "../system/global.h"

/*
* Enumeration of every existing job. These are used as global identifiers that every participating system knows.
* Based on this flag, the data that is received is cast.
*/
enum MessageTypes
{
	ID_CLIENT_INFORMATION_REQUEST = ID_USER_PACKET_ENUM,
	ID_CLIENT_INFORMATION,
	ID_REMOVE_CLIENT,
	ID_CHAT_MESSAGE,
	ID_LEVELINFO,
	ID_START_GAME,
	ID_LEVELFILE,
	ID_CLIENT_READY,
	ID_GOTO_LEVELBEGIN,
	ID_STARTLEVEL,
	ID_OPEN_ENTRIES,
	ID_START_SPAWN
};

/*
* This class represents a job. A job is simply a message that has to be sent or that was already received. The job
* then contains the raw data of the message and a few other information like who was the sender or who has to get
* the message or whether it should be broadcast by the server.
* Think of this like a letter: The content that matters is inside but there is still information necessary to
* get the letter delivered, like the address of the recipient.
* Note that this class works more like a structure. Therefore, there are no getters or setters, since each attribute
* is meant to be modified or read by external classes.
*/
class Job
{
private:
	/*
	* Sets the standard values for the job reliability, priority and broadcast flag.
	*/
	void InitStandardValues()
	{
		reliability = RELIABLE_ORDERED;
		priority = MEDIUM_PRIORITY;
		broadcast = false;
	}

public:
	// Contains the message itself. The first byte contains the type id of the message. This information is used
	// so that the data can be cast accordingly.
	RakNet::BitStream* data;

	// The guid of the sender of the message. If we receive a message, this is the guid of the remote system that
	// sent it. If we send a message, when this can be left empty.
	std::string sender_guid;

	// The guid of the receiver of the message. If we receive a message, this is our own guid. If we send a
	// message as a server, this has to contain the client to send the message to; it can be left empty
	// if we broadcast a message. If we send a message as a client, we can also leave this empty which will
	// automatically send the message to the server.
	std::string receive_guid;

	// The reliability of the message. This does only matter if a message is to be sent. Default is reliable ordered.
	PacketReliability reliability;

	// The priority of the message. This does only matter if a message is to be sent. Default is medium priority.
	PacketPriority priority;

	// Send the message to every client or not.
	bool broadcast;

	/*
	* Constructs an empty job with no data.
	*/
	Job()
	{
		InitStandardValues();
	}

	/*
	* Constructs a job with the type id set.
	*/
	Job(unsigned char id)
	{
		data = new RakNet::BitStream;
		data->Write(id);
		InitStandardValues();
	}

	void JobDone()
	{
		delete data;
	}
};

#endif